home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / ibm / fasrc1p2.arc / DO11.C < prev    next >
C/C++ Source or Header  |  1990-07-15  |  7KB  |  319 lines

  1. /*
  2.  *      MC68HC11 specific processing
  3.  */
  4.  
  5. #define PAGE1   0x00
  6. #define PAGE2   0x18
  7. #define PAGE3   0x1A
  8. #define PAGE4   0xCD
  9.  
  10. /* addressing modes */
  11. #define IMMED   0
  12. #define INDX    1
  13. #define INDY    2
  14. #define LIMMED  3       /* long immediate */
  15. #define OTHER   4
  16.  
  17. int     yflag = 0;      /* YNOIMM, YLIMM, and CPD flag */
  18.  
  19. /*
  20.  *      localinit --- machine specific initialization
  21.  */
  22. localinit()
  23. {
  24. }
  25.  
  26. /*
  27.  *      do_op --- process mnemonic
  28.  *
  29.  *    Called with the base opcode and it's class. Optr points to
  30.  *    the beginning of the operand field.
  31.  */
  32. do_op(opcode,class)
  33. int opcode;    /* base opcode */
  34. int class;    /* mnemonic class */
  35. {
  36.     char *skip_white();
  37.     char c;
  38.     int     dist;   /* relative branch distance */
  39.     int     amode;  /* indicated addressing mode */
  40.     char    *peek;
  41.  
  42.     /* guess at addressing mode */
  43.     peek = Optr;
  44.     amode = OTHER;
  45.     if( head(Operand,"X") || head(Operand,"x") ) {
  46.         if( delim(*(Operand+1)) )
  47.             amode == INDX;
  48.         }
  49.     else if( head(Operand,"Y") || head(Operand,"y") ) {
  50.         if( delim(*(Operand+1)) )
  51.             amode == INDY;
  52.         }
  53.     else while( !delim(*peek) ) { /* check for comma in operand field */
  54.         if( *peek++ == ',' ){
  55.             if( mapdn(*peek) == 'y' )
  56.                 amode = INDY;
  57.             else {
  58.                 amode = INDX;
  59.                 if( mapdn(*peek) != 'x' )
  60.                             error("Must use X or Y register");
  61.                     }
  62.             break;
  63.             }
  64.         }
  65.     if( *Optr == '#' ) amode = IMMED;
  66.  
  67.     yflag = 0;
  68.     switch(class){
  69.         case P2INH:
  70.             emit(PAGE2);
  71.         case INH:                       /* inherent addressing */
  72.             emit(opcode);
  73.             return;
  74.         case REL:                       /* relative branches */
  75.             if( eval() )
  76.                 dist = Result - (Pc+2);
  77.             else dist = -2;
  78.             emit(opcode);
  79.             if( (dist >127 || dist <-128) && Pass==2){
  80.                 error("Branch out of Range");
  81.                 dist = -2;
  82.                 }
  83.             emit(lobyte(dist));
  84.             return;
  85.         case LONGIMM:
  86.             if( amode == IMMED )
  87.                 amode = LIMMED;
  88.         case NOIMM:
  89.             if( amode == IMMED ){
  90.                 error("Immediate Addressing Illegal");
  91.                 return;
  92.                 }
  93.         case GEN:                       /* general addressing */
  94.             do_gen(opcode,amode,PAGE1,PAGE1,PAGE2);
  95.             return;
  96.         case GRP2:
  97.             if( amode == INDY ){
  98.                 Cycles++;
  99.                 emit(PAGE2);
  100.                 amode = INDX;
  101.                 }
  102.             if( amode == INDX )
  103.                 do_indexed(opcode);
  104.             else{   /* extended addressing */
  105.                 eval();
  106.                 emit(opcode+0x10);
  107.                 eword(Result);
  108.                 }
  109.             return;
  110.         case CPD:               /* cmpd */
  111.             if( amode == IMMED )
  112.                 amode = LIMMED;
  113.             if( amode == INDY )
  114.                 yflag=1;
  115.             do_gen(opcode,amode,PAGE3,PAGE3,PAGE4);
  116.             return;
  117.         case XNOIMM:            /* stx */
  118.             if( amode == IMMED ){
  119.                 error("Immediate Addressing Illegal");
  120.                 return;
  121.                 }
  122.         case XLIMM:             /* cpx, ldx */
  123.             if( amode == IMMED )
  124.                 amode = LIMMED;
  125.             do_gen(opcode,amode,PAGE1,PAGE1,PAGE4);
  126.             return;
  127.         case YNOIMM:            /* sty */
  128.             if( amode == IMMED ){
  129.                 error("Immediate Addressing Illegal");
  130.                 return;
  131.                 }
  132.         case YLIMM:             /* cpy, ldy */
  133.             if(amode == INDY)
  134.                 yflag=1;
  135.             if( amode == IMMED )
  136.                 amode = LIMMED;
  137.             do_gen(opcode,amode,PAGE2,PAGE3,PAGE2);
  138.             return;
  139.         case BTB:               /* bset, bclr */
  140.         case SETCLR:            /* brset, brclr */
  141.             opcode = bitop(opcode,amode,class);
  142.  
  143.             if (amode == INDX)
  144.                 Cycles++;
  145.             else if( amode == INDY ){
  146.                 Cycles+=2;
  147.                 emit(PAGE2);
  148.                 amode = INDX;
  149.                 }
  150.             emit(opcode);
  151.             Result = 0;    /* setup in case eval() not called */
  152.             Force_byte = 0;
  153.             Force_word = 0;
  154.             c = mapdn(*Optr);
  155.             if( c != ',' ) {
  156.                if( c != 'x' && c != 'y' || !delim(*(Optr+1)) ) {
  157.                 eval();
  158.                 if( amode == INDX )
  159.                    if( *Optr++ != ',')
  160.                       error("Missing comma");
  161.                 }
  162.                }
  163.             else Optr++;
  164.             if( Result < 0 || Result > 255)
  165.                 warn("Value Truncated");
  166.  
  167.             emit(lobyte(Result));   /* address */
  168.             if( amode == INDX )
  169.                 Optr++;      /* skip x or y */
  170.             Optr = skip_white(Optr);
  171.             eval();
  172.             if( (unsigned int)Result > 0xFF )
  173.                 error("Bit mask more than 8 bits");
  174.             emit(lobyte(Result));   /* mask */
  175.             if( class == SETCLR )
  176.                 return;
  177.             Optr = skip_white(Optr);
  178.             if( eval() )
  179.                 dist = Result - (Pc+1);
  180.             else dist = Old_pc - (Pc + 1);
  181.             if( (dist >127 || dist <-128) && Pass==2){
  182.                 error("Branch out of Range");
  183.                 dist = Old_pc - (Pc+1);
  184.                 }
  185.             emit(lobyte(dist));
  186.             return;
  187.         default:
  188.             fatal("Error in Mnemonic table");
  189.         }
  190. }
  191.  
  192. /*
  193.  *      bitop --- adjust opcode on bit manipulation instructions
  194.  */
  195. bitop(op,mode,class)
  196. int op;
  197. int mode;
  198. int class;
  199. {
  200.     if( mode == INDX || mode == INDY )
  201.         return(op);
  202.     if( class == SETCLR )
  203.         return(op-8);
  204.     else if(class==BTB)
  205.         return(op-12);
  206.     else
  207.         fatal("Assembler error in subroutine bitop()");
  208. }
  209.  
  210. /*
  211.  *      do_gen --- process general addressing modes
  212.  */
  213. do_gen(op,mode,pnorm,px,py)
  214. int     op;     /* base opcode */
  215. int     mode;   /* addressing mode */
  216. int     pnorm;  /* page for normal addressing modes: IMM,DIR,EXT */
  217. int     px;     /* page for INDX addressing */
  218. int     py;     /* page for INDY addressing */
  219. {
  220.     switch(mode){
  221.     case LIMMED:
  222.         Optr++;
  223.         epage(pnorm);
  224.         emit(op);
  225.         eval();
  226.         eword(Result);
  227.         break;
  228.     case IMMED:
  229.         Optr++;
  230.         epage(pnorm);
  231.         emit(op);
  232.         eval();
  233.         emit(lobyte(Result));
  234.         break;
  235.     case INDY:
  236.         if(yflag)
  237.             Cycles += 2;
  238.         else
  239.             Cycles += 3;
  240.         epage(py);
  241.         do_indexed(op+0x20);
  242.         break;
  243.     case INDX:
  244.         Cycles+=2;
  245.         epage(px);
  246.         do_indexed(op+0x20);
  247.         break;
  248.     case OTHER:
  249.         eval();
  250.         epage(pnorm);
  251.         if(Force_word){
  252.             emit(op+0x30);
  253.             eword(Result);
  254.             Cycles+=2;
  255.             break;
  256.             }
  257.         if(Force_byte){
  258.             emit(op+0x10);
  259.             emit(lobyte(Result));
  260.             Cycles++;
  261.             break;
  262.             }
  263.         if(Result>=0 && Result <=0xFF){
  264.             emit(op+0x10);
  265.             emit(lobyte(Result));
  266.             Cycles++;
  267.             break;
  268.             }
  269.         else {
  270.             emit(op+0x30);
  271.             eword(Result);
  272.             Cycles+=2;
  273.             break;
  274.             }
  275.         break;
  276.     default:
  277.         error("Unknown Addressing Mode");
  278.     }
  279. }
  280.  
  281. /*
  282.  *      do_indexed --- handle all wierd stuff for indexed addressing
  283.  */
  284. do_indexed(op)
  285. int op;
  286. {
  287.     char c;
  288.  
  289.     emit(op);
  290.     Result = 0;        /* setup in case eval() not called */
  291.     Force_byte = 0;
  292.     Force_word = 0;
  293.     c = mapdn(*Optr);
  294.     if( c != ',' ) {
  295.         if( c != 'x' && c != 'y' || !delim(*(Optr+1)) ) {
  296.             eval();
  297.             if( *Optr++ != ',' )
  298.             error("Missing comma");
  299.             }
  300.         }
  301.     else Optr++;
  302.     c = mapdn(*Optr++);
  303.     if( c != 'x' && c != 'y')
  304.         warn("Indexed Addressing Assumed");
  305.     if( Result < 0 || Result > 255)
  306.         warn("Value Truncated");
  307.     emit(lobyte(Result));
  308. }
  309.  
  310. /*
  311.  *      epage --- emit page prebyte
  312.  */
  313. epage(p)
  314. int p;
  315. {
  316.     if( p != PAGE1 )        /* PAGE1 means no prebyte */
  317.         emit(p);
  318. }
  319.